class WebcomicsController < ApplicationController
    
  before_filter :login_required, :except => [:show, :index, :show_comments, :show_all_comments,
                                         :show_new_comment, :show_previous_comment, :show_next_comment, :show_strip,
                                         :show_next_strip, :show_previous_strip,
                                         :show_most_recent_strip,
                                         :show_random_strip, :show_first_strip, :display_by,
                                         :display_by_category, :display_categories, :display_by_title,
                                         :display_recently_updated, :display_webcomics_in_category, :display_recently_added,
                                         :show_most_recent_strip_render, :do_search, :search]
  before_filter :check_user, :except => [:index, :show, :show_comments, :show_all_comments, :show_new_comment,
                                         :show_previous_comment, :show_next_comment, :show_strip,
                                         :delete_comment, :edit_comment, :update_comment, 
                                         :show_next_strip, :show_previous_strip,
                                         :show_most_recent_strip,
                                         :show_random_strip, :show_first_strip,
                                         :show_most_recent_strip_render,:display_by,:display_recently_updated, :display_webcomics_in_category,
                                         :display_by_category, :display_categories, :display_by_title,:display_recently_added,
                                         :new, :create, :manage, :do_search, :search]
  before_filter :clearRelevantSessionItems, :except => [:show_comments, :show_all_comments, :show_new_comment,
                                         :comment_rating, :edit_comment, :cancel_edit_comment, :update_comment,
                                         :delete_comment, :show_previous_comment, :show_next_comment, :show_strip, 
                                         :show_next_strip, :show_previous_strip,
                                         :show_most_recent_strip,
                                         :show_random_strip, :show_first_strip,
                                         :show_most_recent_strip_render, :manage, :search_form, :results, :search]
  before_filter :check_creator, :only => [:delete_comment, :edit_comment, :update_comment]
  
  def check_creator
    chk_comment = Comment.find(params[:comment_id])
    #chk_webcomic = Webcomic.find(params[:id])
    unless chk_comment.user_id == current_user.id || @webcomic.creator_id == current_user.id
      access_denied
    end
  end

 def access_denied
    if logged_in?
      render :text => "You have insufficient permissions", :status => 401
      return false
    else
      super
    end
  end

 def check_user
    @webcomic = Webcomic.find(params[:id])
    unless @webcomic.creator_id == current_user.id
      access_denied
    end
  end

  # GET /webcomics
  # GET /webcomics.xml
  def index
    @webcomics = Webcomic.find(:all, :order => "title ASC")    

    if params[:id] == "home"
      display_recently_updated
    else
      if params[:type] == "category"
        display_category_external(params[:cat_id])
      else
        display_by_title
      end        
    end
    
    
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @webcomics }
    end
  end

  # GET /webcomics/1
  # GET /webcomics/1.xml
  def show
    @webcomic = Webcomic.find(params[:id])
    @creator = User.find(@webcomic.creator_id)
    @webcomic.number_of_views = @webcomic.number_of_views + 1
    @webcomic.save
    
    show_most_recent_strip()
    
    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @webcomic }
      #format.js
    end
  end
  
  def show_comments(index, show_all, c_render)  
    @pn_comments = { }
    @num_of_comments = 0;
    session[:displayed_comment_index] = index

    # only time displayed_strip is not null is when show_strip/show_new_comment calls show_comments
    @displayed_strip ||= Strip.find(params[:strip_id])

    @comments = Comment.find_all_by_strip_id(@displayed_strip.id, :order=>"created_at DESC")
      
    @num_of_comments = @comments.length
    if !show_all
      index = index * 5;
      @comments = @comments[index..index+4]
      if index >= 5
        @pn_comments[:previous] = true;
      end
      if index+5 < @num_of_comments
        @pn_comments[:next] = true;
      end
    end
      
    # ensures that show_comments won't try to render a page if show_strip is rendering
    if c_render
      render :update do |page|
        page[:show_five_comments].reload
      end
    end

  end

  def comment_rating
    @r_comment = Comment.find(params[:comment_id])
    @r_comment.update_attribute(:commentrating, params[:r_value])
    #@r_comment.commentrating = 4
    
    show_comments(session[:displayed_comment_index],false,true)
  end
  
  def edit_comment
    @displayed_strip = Strip.find(params[:strip_id])
    @comment_to_edit = Comment.find(params[:comment_id])
    
    render :partial => "comment_edit_form"

  end
  
  def update_comment
    @displayed_strip = Strip.find(params[:strip_id])
    @comment_to_edit = Comment.find(params[:comment_id])
    @comment_to_edit.update_attribute(:contents, params[:contents])
    
    show_comments(session[:displayed_comment_index], false, false)
    
    render :update do |page|
      page[:show_five_comments].replace_html(:comment_form, :partial => "webcomics/comment_new_form")
      page[:show_five_comments].reload
    end
  end
  
  def delete_comment
    @comment_to_d = Comment.find(params[:comment_id])
    @comment_to_d.destroy
    
    show_comments(session[:displayed_comment_index], false, true)
  end

  def edit_comment
    @displayed_strip = Strip.find(params[:strip_id])
    @comment_to_edit = Comment.find(params[:comment_id])
    
    render :partial => "comment_edit_form"

  end

  def cancel_edit_comment
    show_comments(session[:displayed_comment_index],false,false)
    
    render :update do |page|
      page[:show_five_comments].replace_html(:comment_form, :partial => "webcomics/comment_new_form")
      page[:show_five_comments].reload
    end
  end
  
  def update_comment
    @displayed_strip = Strip.find(params[:strip_id])
    @comment_to_edit = Comment.find(params[:comment_id])
    @comment_to_edit.update_attribute(:contents, params[:contents])
    
    show_comments(session[:displayed_comment_index], false, false)
    
    render :update do |page|
      page[:show_five_comments].replace_html(:comment_form, :partial => "webcomics/comment_new_form")
      page[:show_five_comments].reload
    end
  end
  
  def delete_comment
    @comment_to_d = Comment.find(params[:comment_id])
    @comment_to_d.destroy
    
    show_comments(session[:displayed_comment_index], false, true)
  end

  def show_new_comment
    @displayed_strip = Strip.find(params[:strip_id])
    @new_comment = Comment.new
    @new_comment.contents = params[:contents]
    @new_comment.strip = @displayed_strip
    @new_comment.user = current_user
    @new_comment.save
    
    show_comments(0,false,true)
  end

  def show_all_comments
    show_comments(0, true, true)
  end
  
  def show_previous_comment
    show_comments(session[:displayed_comment_index] - 1, false, true)
  end
  
  def show_next_comment
    show_comments(session[:displayed_comment_index] + 1, false, true)
  end
  
  def show_next_strip
    show_strip(session[:displayed_strip_number] + 1, true)
  end

  def show_previous_strip
    show_strip(session[:displayed_strip_number] - 1, true)
  end
  
  def show_most_recent_strip
    @webcomic = Webcomic.find(params[:id])    
    most_recent_strip = @webcomic.find_most_recent_strip()
    if most_recent_strip
      show_strip(most_recent_strip.strip_number, false)
    else
      show_strip(nil, false)
    end

  end

  def show_most_recent_strip_render
    @webcomic = Webcomic.find(params[:id])    
    most_recent_strip = @webcomic.find_most_recent_strip()
    if most_recent_strip
      show_strip(most_recent_strip.strip_number, true)
    else
      show_strip(nil, true)
    end
  end

  def show_random_strip
    @webcomic = Webcomic.find(params[:id])
    @most_recent_strip = @webcomic.find_most_recent_strip()
    @random = 1 + rand(@most_recent_strip.strip_number);
    while (@random == session[:displayed_strip_number])
        @random = 1 + rand(@most_recent_strip.strip_number);
    end
    show_strip(@random, true)
  end

  def show_first_strip
    @webcomic = Webcomic.find(params[:id])
    show_strip(1, true)
  end
  
  def display_by
    if params[:type] == "title"
      display_by_title
    elsif params[:type] == "recentlyupdated"
      display_recently_updated
    elsif params[:type] == "categoryList"
      display_categories
    elsif params[:type] == "popular"
      display_most_popular
    elsif params[:type] == "recentlyadded"
      display_recently_added
    end
   

    render :update do |page|
      page.replace_html :display_by, :partial => "webcomics/display_by"
    end
  end

  def display_webcomics_in_category
    if params[:type] == "allcategories"
      display_by_category(-1)
    else
      display_by_category(params[:cat_id])      
    end

    
    render :update do |page|
      page.replace_html :id_insert_webcomics_in_category_here, :partial => "webcomics/webcomics_in_categories"
    end
  end

  def display_category_external(p_cat_id)
    display_categories
    display_by_category(p_cat_id)
  end  

  def listCreate
    @webcomics = Webcomic.find(:all, :order => "title ASC")    
  end
  
  # GET /webcomics/new
  # GET /webcomics/new.xml
  def new
    @category_list = Category.getCategoryList();
    @webcomic = Webcomic.new
    
    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @webcomic }
    end
  end

  # GET /webcomics/1/edit
  def edit
    @category_list = Category.getCategoryList();
  end

  # POST /webcomics
  # POST /webcomics.xml
  def create
    @category_list = Category.getCategoryList();
    @webcomic = Webcomic.new(params[:webcomic])
    @categories_list = parseCheckbox();
    @categories_list.map!{|c| Category.find_by_name(c)};
    @categories_list.sort!
    @webcomic.categories << @categories_list;

    # @webcomic.save;
    @webcomic.creator_id = current_user.id

    respond_to do |format|
      if @webcomic.save
        flash[:notice] = 'Webcomic was successfully created.'
        format.html { redirect_to :controller => "webcomic", :action => "manage" }
        format.xml  { render :xml => @webcomic, :status => :created, :location => @webcomic }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @webcomic.errors, :status => :unprocessable_entity }
      end
    end
    
  end

  def parseCheckbox() 
    checkboxResults = params[:checkbox];
    categories = Array.new;
    if (checkboxResults == nil) 
      return categories
    end
    for cb in checkboxResults 
      if (cb[1] == "1") 
        categories << cb[0]
      end
    end
    return categories;
  end
    # PUT /webcomics/1
  # PUT /webcomics/1.xml
  def update
    @categories_list = parseCheckbox();
    @categories_list.map!{|c| Category.find_by_name(c)};
    @categories_list.sort!
    @webcomic.categories = Array.new
    @webcomic.categories << @categories_list;
    
    respond_to do |format|
      if @webcomic.update_attributes(params[:webcomic])
        flash[:notice] = 'Webcomic was successfully updated.'
        format.html { redirect_to(@webcomic) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @webcomic.errors, :status => :unprocessable_entity }
      end
    end
  end

  def manage
    @webcomics = Webcomic.find(:all, :conditions => {:creator_id => current_user.id})
    @webcomics = Webcomic.find(:all, :order => "title desc")
  end
  
  # DELETE /webcomics/1
  # DELETE /webcomics/1.xml
  def destroy
    @webcomic.destroy

    respond_to do |format|
      format.html { redirect_to(webcomics_url) }
      format.xml  { head :ok }
    end
    
  end
  
  def do_search
    @results = nil
    
    #user specified a webcomic title
    #@results is empty but not nil when no webcomics can be found
    if !params[:title].empty?
      @results = Webcomic.find(:all, :conditions => ['title LIKE ? ', '%'+params[:title]+'%'])      
    end

    chosen_categories = parseCheckbox();
    chosen_categories.map!{|c| Category.find_by_name(c)};
    chosen_categories.sort!
    
    #user specified some categories
    if !chosen_categories.empty?
      #user specified a title, filter out results with appropriate categories
      if @results && !@results.empty?
        new_result = []
        @results.each do |comic|
          chosen_categories.each do |cat|
            if comic.categories.include?(cat)
              new_result << comic
              break
            end
          end
        end
        
        @results = new_result.uniq
        
      #user did not specify a title, look for all webcomics containing specified categories
      elsif !@results
        @results = []
        for category in chosen_categories
          for comic in category.webcomics
            @results << comic
          end
        end
        @results = @results.uniq
        #@results = Webcomic.find_all_by_categories(chosen_categories)
      end
    end
    
    @test = Category.find(:all)
    @test << Category.find(:first)
    
    #Good to check if empty even if implementation has default value
    if !params[:last_updated].empty?
      to_compare = nil
      case params[:last_updated]
      when "1"
        to_compare = 1.day.ago
      when "2"
        to_compare = 1.week.ago
      when "3"
        to_compare = 1.month.ago
      when "4"
        to_compare = 1.year.ago
      else
        to_compare = nil
      end
      
      if @results && !@results.empty? && to_compare
        new_result = []
        @results.each do |comic|
          if comic.updated_at >= to_compare
            new_result << comic
          end
        end
        @results = new_result
      elsif !@results
        @results = Webcomic.find(:all, :conditions => [ "updated_at >= ?", params[:last_updated] ] )
      end
    end
    
    #if nothing is specified, return all
    if @results.nil?
      @results = Webcomic.find(:all)
    end
    
    respond_to do |format|
      format.html { render :action => "results" }
    end
  end
  
  def results
    respond_to do |format|
      format.html
    end
  end
  
  def search
    @category_list = Category.find(:all)
    respond_to do |format|
      format.html
    end
  end

  protected

  def clearRelevantSessionItems
    session[:displayed_strip_number] = nil
    session[:displayed_comment_index] = nil
  end
  
  def display_by_title
    @result = { :type => :title, :heading => "Browsing by Title", :data => {}}

    for webcomic in @webcomics
      currentLetter = webcomic.title[0,1].upcase
      @result[:data][currentLetter] = (@result[:data][currentLetter] || []) + [webcomic]
    end
    
  end

  def display_recently_updated
    @result = { :type => :recentlyupdated, :heading => "Recently Updated", :data => []}
    @result[:data] = Webcomic.find(:all, :order => "updated_at DESC", :limit => 10)
  end

  def display_recently_added
    @result = { :type => :recentlyadded, :heading => "Recently Added", :data => []}
    @result[:data] = Webcomic.find(:all, :order => "created_at DESC", :limit => 10)
  end  

  def display_categories
    @result = { :type => :categoryList, :heading => "Browsing by Category", :data => []}
    @result[:data] = Category.find(:all)
  end

  def display_by_category(p_cat_id)
    if p_cat_id.to_i > 0
      @category = Category.find(p_cat_id)
      @result2 = { :type => :category, :heading => ( @category.name), :data => []}
      @result2[:data] = @category.webcomics
    else
      @webcomics = Webcomic.find(:all)
      @result2 = { :type => :allcategories, :heading => ("All Categories"), :data => {}}
      for webcomic in @webcomics
        categories = webcomic.categories
        categories.each do |currentCategory|
          @result2[:data][currentCategory.name] = (@result2[:data][currentCategory.name] || []) + [webcomic]
        end
      end
    end
  end

  def display_most_popular
    @result = { :type => :popular, :heading => "Most Popular", :data => []}
    @result[:data] = Webcomic.find(:all, :order => "number_of_views DESC", :limit => 10)
  end
  
  def show_strip(p_go_to, p_render)
    if !p_go_to
      @displayed_strip_tag = ""
      @cpn_strips = { }
    else
      @webcomic = Webcomic.find(params[:id])
      @cpn_strips = @webcomic.find_strip_and_neighbors(p_go_to)    
      @displayed_strip = @cpn_strips[:current]

      if @displayed_strip == nil
        @displayed_strip = @webcomic.find_strip(session[:displayed_strip_number])
      end
      
      session[:displayed_strip_number] = @displayed_strip.strip_number

      appropriateWidth = [@displayed_strip.width, 600].min().to_s + "px"

      @displayed_strip_tag = "<img src=\"" + @displayed_strip.public_filename() + "\" width=\"" + appropriateWidth +"\"/>"
      
      show_comments(0, false, false)
    end
    
    if p_render
      render :update do |page|
        page.replace_html(:webcomic_navigation_top,:partial => "webcomics/strip_navigation_actions")
        page.replace_html(:webcomic_navigation_bottom,:partial => "webcomics/strip_navigation_actions")
        page[:show_five_comments].reload
        page.replace_html(:id_display_strip_image_here, @displayed_strip_tag)
        @newtitle = '"' + @displayed_strip.title + '"'
        page.replace_html(:id_display_strip_title_here,@newtitle)
      end
    end
    
  end
  
  def testOut 
    @webcomic.categories
  end
end
